package edu.nyu.msis.parser;

import edu.nyu.msis.ds.UseList;
import edu.nyu.msis.utilities.ManagedBuffer;

public class UseListParser {
	UseListStates useListState;
    Integer numOfUseVars, noMoreVars;
    String variable;
    ManagedBuffer managedBuffer;
    UseList useList;

	/**
	 * 
	 */
	public UseListParser() {
		super();
		useListState = UseListStates.WHITE_SPACE_IN_BEGIN;
		numOfUseVars = 0;
		noMoreVars = 0;
        variable = "";
        managedBuffer = new ManagedBuffer();
        useList = null;
	}
	
	public void setUseList(UseList useList) {
		this.useList = useList;
	}
	
	public ParserStates parse(Character readChar) {
        switch (useListState) {
            case WHITE_SPACE_IN_BEGIN:
                {
                    if (Character.isWhitespace(readChar)) {
                        useListState = UseListStates.WHITE_SPACE_IN_BEGIN;
                    }
                    else if (Character.isDigit(readChar)) {
                    	managedBuffer.addCharToBuffer(readChar);
                        useListState = UseListStates.GET_NUM_USE;
                    }
                    else if (Character.isLetter(readChar)) {
                        return ParserStates.ERROR_STATE;
                    }
                    else {
                        return ParserStates.ERROR_STATE;
                    }
                    return ParserStates.USE_LIST_BEGIN;
                }
            case GET_NUM_USE:
                {
                    if (Character.isWhitespace(readChar)) {
                        numOfUseVars = managedBuffer.convertBuffToInt();
                        useList.setSize(numOfUseVars);//Add number variables to use list
                        if (numOfUseVars == 0) {
                        	return ParserStates.USE_LIST_END;
                        }
                        else {
                        	noMoreVars = numOfUseVars;
                            useListState = UseListStates.GOT_NUM_USE;
                        }                        
                    }
                    else if (Character.isDigit(readChar)) {
                        managedBuffer.addCharToBuffer(readChar);
                        useListState = UseListStates.GET_NUM_USE;
                    }
                    else if (Character.isLetter(readChar)) {
                        return ParserStates.ERROR_STATE;
                    }
                    else {
                        return ParserStates.ERROR_STATE;
                    }
                    return ParserStates.USE_LIST_BEGIN;
                }
            case GOT_NUM_USE:
                {
                    if (Character.isWhitespace(readChar)) {
                        useListState = UseListStates.GOT_NUM_USE;
                    }
                    else if (Character.isDigit(readChar)) {
                        return ParserStates.ERROR_STATE;
                    }
                    else if (Character.isLetter(readChar)) {
                        managedBuffer.addCharToBuffer(readChar);
                        useListState = UseListStates.GET_USE_VAR_NAME;
                    }
                    else {
                        return ParserStates.ERROR_STATE;
                    }
                    return ParserStates.USE_LIST_BEGIN;
                }
            case GET_USE_VAR_NAME:
                {
                    if (Character.isWhitespace(readChar) && (noMoreVars > 0)) {
                    	//Need to look more vars
                    	variable = managedBuffer.convertBuffToString();
                    	useList.addToUsedVars(variable);
                    	noMoreVars--;
                    	if (noMoreVars > 0) {
                    		useListState = UseListStates.GOT_USE_VAR_NAME;
                    	}
                    	else {
                    		return ParserStates.USE_LIST_END;
                    	}
                    	return ParserStates.USE_LIST_BEGIN;
                    }
                    else if (Character.isLetterOrDigit(readChar)) {
                        managedBuffer.addCharToBuffer(readChar);
                        useListState = UseListStates.GET_USE_VAR_NAME;
                        return ParserStates.USE_LIST_BEGIN;
                    }
                    else {
                        return ParserStates.ERROR_STATE;
                    }
                }
            case GOT_USE_VAR_NAME:
	            {
	            	if (Character.isWhitespace(readChar)) {
	            		useListState = UseListStates.GOT_USE_VAR_NAME;
	            	}
	            	else if (Character.isDigit(readChar)) {
	            		return ParserStates.ERROR_STATE;
	            	}
	            	else if (Character.isLetter(readChar)) {
	            		managedBuffer.addCharToBuffer(readChar);
	            		useListState = UseListStates.GET_USE_VAR_NAME;
	            	}
	            	return ParserStates.USE_LIST_BEGIN;
	            }
            default:  //Should never reach here.
                {
                    System.out.println("Invalid UseListParser State [state: " + useListState + ", read: " + readChar + "].");
                    return ParserStates.ERROR_STATE;
                }
        }
	}

    public void reset() {
    	useListState = UseListStates.WHITE_SPACE_IN_BEGIN;
        numOfUseVars = 0;
        noMoreVars = 0;
        variable = "";
    }
}